<script setup lang="ts">
import { ref, onMounted, watch, defineProps, defineExpose, onUnmounted, reactive } from 'vue';
import { LocateSetData, CylinderModelConfig } from '@/utils/appCommon/appCommonOptions/aeLocateConfigModel';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { FontLoader } from 'three/examples/jsm/loaders/FontLoader';
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry';
import { ellipseCircumference, calculateCircleXYByArc, calculateEllipseXYByArc, computeScaleRate } from '@/views/apply/locateAnalysis/component/utils/commonThree';

// 定义接收的props
const props = defineProps<{
  locateSetting: LocateSetData;
  renderParams: {
    width: number;
    height: number;
    viewMode: number;
  };
  searchParams: any;
}>();

// Three.js核心对象
let scene: THREE.Scene | null = new THREE.Scene();
let camera: THREE.PerspectiveCamera | null = new THREE.PerspectiveCamera();
let renderer: THREE.WebGLRenderer | null = new THREE.WebGLRenderer({ antialias: true });
let controls: OrbitControls | null = null;
let raycaster: THREE.Raycaster | null = null;
let mouse: THREE.Vector2 | null = null;

// 模型相关
let capsule: THREE.Group | null = null;
let topSphere: THREE.Mesh | null = null;
let bottomSphere: THREE.Mesh | null = null;
let cylinder: THREE.Mesh | null = null;
let axisLineMeshes: THREE.Object3D[] = [];
let axisTextMeshes: THREE.Object3D[] = [];
let axisLabelFont: any = null;

// 状态管理
const threeBoxRef = ref();
const threeData = reactive({
  width: 600,
  height: 600,
  bgColor: '#f0f4f8',
  scaleRate: 1 // 用于实际尺寸和3D尺寸之间的转换
});
const mousePosition = reactive({
  x: 0,
  y: 0,
  z: 0
});

// 传感器和点的数据结构
const sensors = ref<Array<{
  id: number|string;
  x: number;
  y: number;
  cube: THREE.Mesh;
  dynamicStyle: {
    left: string;
    top: string;
    display: string;
  };
}>>([]);

const points = ref<Array<{
  id: string;
  position: THREE.Vector3;
  mesh: THREE.Mesh;
}>>([]);

// 传感器编号计数器
let sensorCounter = 0;

// 初始化Three.js场景
function initThree() {
  if (!threeBoxRef.value) return;
  // 首先更新threeData的尺寸，确保使用最新的renderParams
  threeData.width = props.renderParams.width;
  threeData.height = props.renderParams.height;

  // 创建场景
  scene.background = new THREE.Color(threeData.bgColor);

  // 创建渲染器
  renderer.setSize(threeData.width, threeData.height);
  threeBoxRef.value.innerHTML = '';
  threeBoxRef.value.appendChild(renderer.domElement);

  // 创建相机
  const cameraY = threeData.width > 100 ? threeData.width : 100;
  camera.position.set(0, -cameraY, 0); // 初始相机位置
  camera.lookAt(scene.position); // 指向原点

  // 创建轨道控制器
  controls = new OrbitControls(camera, renderer.domElement);
  controls.enableDamping = true;
  controls.dampingFactor = 0.05;
  controls.addEventListener('change', () => {
    updateAllTextPosition()
    render()
  });

  // 添加光源
  const light = new THREE.DirectionalLight(0xffffff, 1);
  light.position.set(0, threeData.width, threeData.height);
  scene.add(light);

  // 创建辅助工具
  raycaster = new THREE.Raycaster();
  mouse = new THREE.Vector2();

  // 添加鼠标移动监听
  window.addEventListener('mousemove', listenMouseMove);

  // 初始化胶囊体模型
  createCapsuleModel();

  // 创建坐标轴
  createAxis();

  // 添加初始传感器
  setTimeout(() => {
    addExampleSensors()
  }, 500);
}

// 监听鼠标移动
function listenMouseMove(event: MouseEvent) {
  if (!renderer || !camera || !raycaster || !mouse) return;

  const rect = renderer.domElement.getBoundingClientRect();
  const x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
  const y = -((event.clientY - rect.top) / rect.height) * 2 + 1;

  mouse.set(x, y);
  raycaster.setFromCamera(mouse, camera);

  // 找出所有可交互的物体
  const intersectables: THREE.Object3D[] = [];
  if (capsule) {
    capsule.traverse((child) => {
      if (child instanceof THREE.Mesh) {
        intersectables.push(child);
      }
    });
  }

  // 检查射线相交
  const intersects = raycaster.intersectObjects(intersectables, false);
  if (intersects.length > 0) {
    const intersection = intersects[0];
    const position = intersection.point;

    // 应用缩放率并更新鼠标位置（转换为物理尺寸）
    mousePosition.x = Number((position.x * threeData.scaleRate).toFixed(1));
    mousePosition.y = Number((position.y * threeData.scaleRate).toFixed(1));
    mousePosition.z = Number((position.z * threeData.scaleRate).toFixed(1));
  }
}

// 获取柱面尺寸（考虑缩放）
function getCylinderDimensions() {
  const modelConfig: CylinderModelConfig = props.locateSetting?.config?.modelConfig as CylinderModelConfig;
  const diameter = modelConfig?.cylinderDiameter || 100;
  const cylinderLength = modelConfig?.cylinderLength || 100;
  const sealHeadHeight = modelConfig?.headHeight || 0;

  // 计算缩放率，使用直径和长度中的较大值作为基准
  const maxDimension = Math.max(diameter, cylinderLength);
  const scaleRate = computeScaleRate(maxDimension, 200); // 200作为比较尺寸
  threeData.scaleRate = scaleRate;

  // 转换为3D视图中的尺寸
  return {
    physicalDiameter: diameter,
    physicalLength: cylinderLength,
    physicalSealHeadHeight: sealHeadHeight,
    diameter: Math.max(diameter / scaleRate, 1),
    cylinderLength: Math.max(cylinderLength / scaleRate, 1),
    sealHeadHeight: Math.max(sealHeadHeight / scaleRate, 0),
    scaleRate
  };
}

// 创建胶囊体模型
function createCapsuleModel() {
  if (!scene) return;

  // 清理旧模型
  if (capsule) {
    scene.remove(capsule);
  }
  capsule = new THREE.Group();

  // 获取柱面配置
  const modelConfig: CylinderModelConfig = props.locateSetting?.config?.modelConfig as CylinderModelConfig;
  const sealHeadType = modelConfig?.headType || 'none';

  // 获取缩放后的尺寸
  const { diameter, cylinderLength, sealHeadHeight } = getCylinderDimensions();

  // 创建两个半球体（椭球封头）
  const radius = diameter / 2;
  const longRadius = diameter / 2;
  const shortRadius = sealHeadHeight;
  const widthSegments = 24;
  const heightSegments = 24;

  // 上半球体（上封头）
  const sphereGeometry1 = new THREE.SphereGeometry(
    longRadius,
    widthSegments,
    heightSegments,
    0,
    Math.PI * 2,
    0,
    Math.PI / 2,
  );
  sphereGeometry1.scale(1, shortRadius / longRadius, 1); // 缩放成椭球体
  const sphereMaterial = new THREE.MeshBasicMaterial({
    color: 0xeaeaea,
    transparent: true,
    opacity: 0.9,
  });
  topSphere = new THREE.Mesh(sphereGeometry1, sphereMaterial);
  topSphere.position.set(0, cylinderLength / 2, 0);

  // 下半球体（下封头）
  const sphereGeometry2 = new THREE.SphereGeometry(
    longRadius,
    widthSegments,
    heightSegments,
    0,
    Math.PI * 2,
    Math.PI * 2,
    Math.PI,
  );
  sphereGeometry2.scale(1, shortRadius / longRadius, 1); // 缩放成椭球体
  bottomSphere = new THREE.Mesh(sphereGeometry2, sphereMaterial);
  bottomSphere.position.set(0, -cylinderLength / 2, 0);

  // 创建圆柱体（主体）
  const cylinderGeometry = new THREE.CylinderGeometry(radius, radius, cylinderLength, widthSegments, heightSegments);
  const capsuleMaterial = new THREE.MeshBasicMaterial({
    color: 0xdadada,
    transparent: true,
    opacity: 0.9,
  });
  cylinder = new THREE.Mesh(cylinderGeometry, capsuleMaterial);

  // 根据封头类型添加相应的组件
  if (sealHeadType === 'both' || sealHeadType === 'top') {
    capsule.add(topSphere);
  }
  if (sealHeadType === 'both' || sealHeadType === 'bottom') {
    capsule.add(bottomSphere);
  }
  capsule.add(cylinder);

  // 旋转模型，使Z轴朝上
  capsule.rotation.x = Math.PI / 2;

  // 调整位置，使底部圆心在坐标轴原点
  if (sealHeadType === 'bottom' || sealHeadType === 'both') {
    capsule.position.set(0, 0, sealHeadHeight + cylinderLength / 2);
  } else {
    capsule.position.set(0, 0, cylinderLength / 2);
  }

  // 添加到场景
  scene.add(capsule);
}

// 创建坐标轴
function createAxis() {
  if (!scene) return;

  // 清除现有的坐标轴
  if (axisLineMeshes.length > 0) {
    axisLineMeshes.forEach(item => {
      item.removeFromParent();
    });
    axisLineMeshes = [];
  }
  // 加载字体
  const fontLoader = new FontLoader();
  fontLoader.load('/public/threefont.json', function(font) {
    axisLabelFont = font;
    createAxisHelper(font);
  });
}

// 创建坐标轴辅助
function createAxisHelper(font: any) {
  if (!scene) return;

  // 获取缩放后的尺寸和原始物理尺寸
  const {
    diameter: scaledDiameter,
    cylinderLength: scaledLength,
    sealHeadHeight: scaledSealHeadHeight,
    physicalDiameter,
    physicalLength,
    physicalSealHeadHeight
  } = getCylinderDimensions();

  // 创建材质
  const materialX = new THREE.LineBasicMaterial({ color: 0xff0000 }); // 红色X轴
  const materialY = new THREE.LineBasicMaterial({ color: 0x00ff00 }); // 绿色Y轴
  const materialZ = new THREE.LineBasicMaterial({ color: 0x0000ff }); // 蓝色Z轴

  // 计算轴范围（使用缩放后的尺寸）
  const xmin = 0;
  const xmax = Math.abs(scaledDiameter / 2);
  const xstep = (xmax - xmin) / 5;

  const ymin = 0;
  const ymax = Math.abs(scaledDiameter / 2);
  const ystep = (ymax - ymin) / 5;

  // X轴刻度和标签
  for (let i = xmin; i <= xmax + xstep; i += xstep) {
    // 刻度线
    const geometry = new THREE.BufferGeometry();
    const positions = new Float32Array([
      i, 0, 0,
      i, 0.2, 0
    ]);
    geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
    const line = new THREE.Line(geometry, materialX);
    axisLineMeshes.push(line);
    scene?.add(line);

    // 标签
    if (i > 0) {
      // 根据缩放率计算物理尺寸标签
      const physicalValue = Math.round(i * threeData.scaleRate);
      const textLabel = physicalValue.toString();
      const textGeometry = new TextGeometry(textLabel, {
        font: font,
        size: xstep / 4,
        height: 0.1
      });
      const textMaterial = new THREE.MeshBasicMaterial({ color: 0x888888 });
      const textMesh = new THREE.Mesh(textGeometry, textMaterial);
      textMesh.position.set(i, -0.5, 0.2);
      axisTextMeshes.push(textMesh);
      scene?.add(textMesh);
    }

    // Y轴刻度和标签
    for (let i = ymin; i <= ymax + ystep; i += ystep) {
      // 刻度线
      const geometry = new THREE.BufferGeometry();
      const positions = new Float32Array([
        0, i, 0,
        0.2, i, 0
      ]);
      geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));
      const line = new THREE.Line(geometry, materialY);
      axisLineMeshes.push(line);
      scene?.add(line);

      // 标签
      if (i > 0) {
        // 根据缩放率计算物理尺寸标签
        const physicalValue = Math.round(i * threeData.scaleRate);
        const textLabel = physicalValue.toString();
        const textGeometry = new TextGeometry(textLabel, {
          font: font,
          size: ystep / 4,
          height: 0.1
        });
        const textMaterial = new THREE.MeshBasicMaterial({ color: 0x888888 });
        const textMesh = new THREE.Mesh(textGeometry, textMaterial);
        textMesh.position.set(-0.5, i, 0.2);
        axisTextMeshes.push(textMesh);
        scene?.add(textMesh);
      }

      // XYZ轴线
      // X轴
      const xAxisGeometry = new THREE.BufferGeometry();
      const xAxisPositions = new Float32Array([
        xmin, 0, 0,
        xmax + xstep, 0, 0
      ]);
      xAxisGeometry.setAttribute('position', new THREE.BufferAttribute(xAxisPositions, 3));
      const xAxisLine = new THREE.Line(xAxisGeometry, materialX);
      axisLineMeshes.push(xAxisLine);
      scene?.add(xAxisLine);

      // Y轴
      const yAxisGeometry = new THREE.BufferGeometry();
      const yAxisPositions = new Float32Array([
        0, ymin, 0,
        0, ymax + ystep, 0
      ]);
      yAxisGeometry.setAttribute('position', new THREE.BufferAttribute(yAxisPositions, 3));
      const yAxisLine = new THREE.Line(yAxisGeometry, materialY);
      axisLineMeshes.push(yAxisLine);
      scene?.add(yAxisLine);

      render();
    }
  }
}

// 平面坐标转换为3D坐标
    function transferPlaneDataTo3dData(x: number, y: number): { axisX: number; axisY: number; axisZ: number; correctX?: number } {
      // 获取缩放后的尺寸和原始物理尺寸
      const {
        physicalDiameter,
        physicalLength,
        physicalSealHeadHeight,
        scaleRate
      } = getCylinderDimensions();

      const modelConfig: CylinderModelConfig = props.locateSetting?.config?.modelConfig as CylinderModelConfig;
      const sealHeadType = modelConfig?.headType || 'none';

      // 使用物理尺寸计算椭圆周长（因为x和y是物理坐标）
      const ellipseParameter = ellipseCircumference(physicalDiameter / 2, physicalSealHeadHeight);
      const ellipse1of4 = ellipseParameter / 4;

      // 根据不同的封头类型处理
      if (sealHeadType === 'bottom' || sealHeadType === 'both') {
        if (y < ellipse1of4) {
          // 底封头区域
          const arc1 = ellipse1of4 - y;
          // 使用物理尺寸计算椭圆坐标
          const calRes1 = calculateEllipseXYByArc(arc1, physicalDiameter / 2, physicalSealHeadHeight);

          let correctX = x;
          if (x > Math.PI * 2 * calRes1.x) {
            correctX = Math.PI * 2 * calRes1.x;
          }

          // 使用物理尺寸计算圆坐标
          const calRes2 = calculateCircleXYByArc(correctX, calRes1.x);

          // 将物理坐标转换为缩放后的3D坐标
          return {
            axisX: calRes2.x / scaleRate,
            axisY: calRes2.y / scaleRate,
            axisZ: (physicalSealHeadHeight - calRes1.y) / scaleRate,
            correctX: correctX
          };
        }
      }

      if (sealHeadType === 'bottom' || sealHeadType === 'both') {
        if (y >= ellipse1of4 && y <= ellipse1of4 + physicalLength) {
          // 柱体区域（有底封头）
          let correctX = x;
          if (x > Math.PI * physicalDiameter) {
            correctX = Math.PI * physicalDiameter;
          }

          // 使用物理尺寸计算圆坐标
          const calRes2 = calculateCircleXYByArc(correctX, physicalDiameter / 2);

          // 将物理坐标转换为缩放后的3D坐标
          return {
            axisX: calRes2.x / scaleRate,
            axisY: calRes2.y / scaleRate,
            axisZ: (physicalSealHeadHeight + y - ellipse1of4) / scaleRate,
            correctX: correctX
          };
        }
      }

      if (sealHeadType === 'top' || sealHeadType === 'both') {
        if (sealHeadType === 'both' && y > ellipse1of4 + physicalLength) {
          // 上封头区域（两端都有封头）
          const arc1 = y - physicalLength - ellipse1of4;
          // 使用物理尺寸计算椭圆坐标
          const calRes1 = calculateEllipseXYByArc(arc1, physicalDiameter / 2, physicalSealHeadHeight);

          let correctX = x;
          if (x > Math.PI * 2 * calRes1.x) {
            correctX = Math.PI * 2 * calRes1.x;
          }

          // 使用物理尺寸计算圆坐标
          const calRes2 = calculateCircleXYByArc(correctX, calRes1.x);

          // 将物理坐标转换为缩放后的3D坐标
          return {
            axisX: calRes2.x / scaleRate,
            axisY: calRes2.y / scaleRate,
            axisZ: (physicalSealHeadHeight + physicalLength + calRes1.y) / scaleRate,
            correctX: correctX
          };
        } else if (sealHeadType === 'top' && y > physicalLength) {
          // 上封头区域（只有上封头）
          const arc1 = y - physicalLength;
          // 使用物理尺寸计算椭圆坐标
          const calRes1 = calculateEllipseXYByArc(arc1, physicalDiameter / 2, physicalSealHeadHeight);

          let correctX = x;
          if (x > Math.PI * 2 * calRes1.x) {
            correctX = Math.PI * 2 * calRes1.x;
          }

          // 使用物理尺寸计算圆坐标
          const calRes2 = calculateCircleXYByArc(correctX, calRes1.x);

          // 将物理坐标转换为缩放后的3D坐标
          return {
            axisX: calRes2.x / scaleRate,
            axisY: calRes2.y / scaleRate,
            axisZ: (physicalLength + calRes1.y) / scaleRate,
            correctX: correctX
          };
        }
      }

      if (sealHeadType === 'none') {
        // 无封头情况，只有柱体
        let correctX = x;
        if (x > Math.PI * physicalDiameter) {
          correctX = Math.PI * physicalDiameter;
        }

        // 使用物理尺寸计算圆坐标
        const calRes2 = calculateCircleXYByArc(correctX, physicalDiameter / 2);

        // 将物理坐标转换为缩放后的3D坐标
        return {
          axisX: calRes2.x / scaleRate,
          axisY: calRes2.y / scaleRate,
          axisZ: y / scaleRate,
          correctX: correctX
        };
      }

      if (sealHeadType === 'top' && y <= physicalLength) {
        // 柱体区域（只有上封头）
        let correctX = x;
        if (x > Math.PI * physicalDiameter) {
          correctX = Math.PI * physicalDiameter;
        }

        // 使用物理尺寸计算圆坐标
        const calRes2 = calculateCircleXYByArc(correctX, physicalDiameter / 2);

        // 将物理坐标转换为缩放后的3D坐标
        return {
          axisX: calRes2.x / scaleRate,
          axisY: calRes2.y / scaleRate,
          axisZ: y / scaleRate,
          correctX: correctX
        };
      }

      // 默认返回值
      return {
        axisX: 0,
        axisY: 0,
        axisZ: 0,
        correctX: 0
      };
    }

// 创建传感器立方体
    function createCubeItem(size: number): THREE.Mesh {
      const cubeGeometry = new THREE.BoxGeometry(size, size, size);
      const material = new THREE.MeshBasicMaterial({
        color: 0x1E90FF
      });
      const cube = new THREE.Mesh(cubeGeometry, material);
      return cube;
    }

// 创建传感器
    function createSensorBoxes() {
      if (!scene || !props.locateSetting?.sensorSettings || props.locateSetting.sensorSettings.length === 0) {
        // 如果没有传感器设置，创建一些示例传感器
        addExampleSensors();
        return;
      }

      // 清除旧的传感器
      sensors.value.forEach(item => {
        if (item.cube) {
          scene?.remove(item.cube);
        }
      });
      sensors.value = [];

      // 从配置中创建传感器
      props.locateSetting.sensorSettings.forEach((sensorSetting, index) => {
        const x = sensorSetting.x || 0;
        const y = sensorSetting.y || 0;
        const id = sensorSetting.id || index + 1;

        // 计算3D坐标
        const cubexyz = transferPlaneDataTo3dData(x, y);

        // 创建立方体
        const cube = createCubeItem(5);
        cube.position.set(cubexyz.axisX, cubexyz.axisY, cubexyz.axisZ);
        scene?.add(cube);

        // 判断是否可见
        const isVisible = judgeSensorTextShow(cube);

        // 添加到传感器列表
        sensors.value.push({
          id,
          x,
          y,
          cube,
          dynamicStyle: {
            left: '0px',
            top: '0px',
            display: isVisible ? 'block' : 'none'
          }
        });
      });

      // 更新所有标签位置
      updateAllTextPosition();
      render();
    }

// 创建示例传感器
    function addExampleSensors() {
      if (!scene) return;

      const modelConfig: CylinderModelConfig = props.locateSetting?.config?.modelConfig as CylinderModelConfig;
      const diameter = modelConfig?.cylinderDiameter || 100;
      const cylinderLength = modelConfig?.cylinderLength || 100;
      const sealHeadType = modelConfig?.headType || 'none';
      const sealHeadHeight = modelConfig?.headHeight || 30;

      const ellipseParameter = ellipseCircumference(diameter / 2, sealHeadHeight);
      const ellipse1of4 = ellipseParameter / 4;
      const circumference = Math.PI * diameter;

      // 计算合适的Y起始位置
      let startY = 0;
      if (sealHeadType === 'bottom' || sealHeadType === 'both') {
        startY = ellipse1of4;
      }

      // 添加一些示例传感器
      addSensor(circumference * 0.1, startY + cylinderLength * 0.2);
      addSensor(circumference * 0.3, startY + cylinderLength * 0.5);
      addSensor(circumference * 0.6, startY + cylinderLength * 0.7);
      addSensor(circumference * 0.8, startY + cylinderLength * 0.3);

      render();
    }

// 添加传感器
    function addSensor(x: number, y: number, existingId?: number): number {
      if (!scene) return -1;

      const currentId = existingId || sensorCounter++;

      // 计算3D坐标
      const { axisX, axisY, axisZ } = transferPlaneDataTo3dData(x, y);

      // 创建传感器立方体
      const cube = createCubeItem(5);
      cube.position.set(axisX, axisY, axisZ);
      scene.add(cube);

      // 判断是否可见
      const isVisible = judgeSensorTextShow(cube);

      // 添加传感器数据
      sensors.value.push({
        id: currentId,
        x,
        y,
        cube,
        dynamicStyle: {
          left: '0px',
          top: '0px',
          display: isVisible ? 'block' : 'none'
        }
      });

      // 更新标签位置
      updateTextPosition(sensors.value.length - 1, cube);

      render();
      return currentId;
    }

// 删除传感器
    function removeSensor(id: number|string): boolean {
      if (!scene) return false;

      const index = sensors.value.findIndex(sensor => sensor.id === id);
      if (index === -1) return false;

      // 移除3D对象
      scene.remove(sensors.value[index].cube);

      // 从数组中删除
      sensors.value.splice(index, 1);

      render();
      return true;
    }

// 添加点
    function addPoint(x: number, y: number, z: number, id?: string): string {
      if (!scene) return '';

      const pointId = id || `point_${Date.now()}`;
      const position = new THREE.Vector3(x, y, z);

      // 创建点的几何体
      const pointGeometry = new THREE.SphereGeometry(3, 8, 8);
      const pointMaterial = new THREE.MeshBasicMaterial({ color: 0xFF3333 });
      const pointMesh = new THREE.Mesh(pointGeometry, pointMaterial);
      pointMesh.position.copy(position);
      scene.add(pointMesh);

      // 存储点信息
      points.value.push({
        id: pointId,
        position,
        mesh: pointMesh
      });

      render();
      return pointId;
    }

// 移除点
    function removePoint(id: string): boolean {
      if (!scene) return false;

      const index = points.value.findIndex(point => point.id === id);
      if (index === -1) return false;

      // 移动物体
      scene.remove(points.value[index].mesh);

      // 从数组中删除
      points.value.splice(index, 1);

      render();
      return true;
    }

// 判断传感器文本是否应该显示（是否被遮挡）
    function judgeSensorTextShow(sensor: THREE.Mesh): boolean {
      if (!camera) return true;

      // 获取传感器的世界位置
      const sensorWorldPosition = new THREE.Vector3();
      sensor.getWorldPosition(sensorWorldPosition);

      const cameraWorldPosition = new THREE.Vector3();
      camera.getWorldPosition(cameraWorldPosition);

      // 计算向量
      const direction = new THREE.Vector3().subVectors(sensorWorldPosition, cameraWorldPosition);
      const distance = direction.length();
      direction.normalize();

      // 从相机位置向传感器方向发射射线
      if (!raycaster) raycaster = new THREE.Raycaster();
      raycaster.set(cameraWorldPosition, direction);

      // 找出所有可能遮挡的物体（排除传感器自身）
      const obstacles: THREE.Object3D[] = [];
      if (capsule) {
        capsule.traverse((child) => {
          if (child instanceof THREE.Mesh && child !== sensor) {
            obstacles.push(child);
          }
        });
      }

      // 检查射线是否与任何障碍物相交
      const intersects = raycaster.intersectObjects(obstacles, false);

      // 如果有相交，且交点距离小于到传感器的距离，则被遮挡
      for (const intersect of intersects) {
        if (intersect.distance < distance - 1) { // 减1避免精度问题
          return false;
        }
      }

      return true;
    }

// 更新单个文本位置
    function updateTextPosition(index: number, cube: THREE.Mesh) {
      if (!camera || !renderer) return;

      // 将3D位置转换为屏幕坐标
      const vector = new THREE.Vector3();
      cube.getWorldPosition(vector);
      vector.project(camera);

      const x = (vector.x * 0.5 + 0.5) * props.renderParams.width;
      const y = (-vector.y * 0.5 + 0.5) * props.renderParams.height;

      // 更新样式
      if (sensors.value[index]) {
        sensors.value[index].dynamicStyle.left = `${x}px`;
        sensors.value[index].dynamicStyle.top = `${y}px`;

        // 判断是否可见
        sensors.value[index].dynamicStyle.display = judgeSensorTextShow(cube) ? 'block' : 'none';
      }
    }

// 更新所有文本位置
    function updateAllTextPosition() {
      sensors.value.forEach((item, index) => {
        if (item.cube) {
          updateTextPosition(index, item.cube);
        }
      });
    }

// 渲染场景
    function render() {
      if (renderer && scene && camera) {
        renderer.render(scene, camera);
      }
    }

// 调整渲染器大小
    function resizeRenderer() {
      if (!renderer || !camera || !threeBoxRef.value) return;

      renderer.setSize(props.renderParams.width, props.renderParams.height);

      if (camera) {
        camera.aspect = props.renderParams.width / props.renderParams.height;
        camera.updateProjectionMatrix();
      }

      updateAllTextPosition();
      render();
    }

// 清理资源
    function cleanup() {
      if (renderer) {
        renderer.dispose();
      }
      if (controls) {
        controls.dispose();
      }

      // 移除事件监听器
      window.removeEventListener('mousemove', listenMouseMove);

      // 清理3D对象
      if (scene) {
        scene.clear();
      }

      // 清理引用
      axisLineMeshes = [];
      axisTextMeshes = [];
      sensors.value = [];
      points.value = [];
    }

// 监听参数变化
    watch(() => props.locateSetting, (newVal) => {
      console.log('CylinderFace3D - 定位配置变化:', newVal);
      // 重新创建模型和传感器
      createCapsuleModel();
      createAxis();
      //createSensorBoxes();
    }, { deep: true, immediate: true });

    watch(() => props.renderParams, (newVal) => {
      console.log('CylinderFace3D - 渲染参数变化:', newVal);
      resizeRenderer();
    }, { deep: true, immediate: true });

    watch(() => props.searchParams, (newVal) => {
      console.log('CylinderFace3D - 搜索参数变化:', newVal);
      // 3D视图对searchParams变化的处理逻辑
    }, { deep: true, immediate: true });

// 组件挂载
    onMounted(() => {
      console.log('CylinderFace3D组件已挂载');
      initThree();
    });

// 组件卸载
    onUnmounted(() => {
      console.log('CylinderFace3D组件已卸载');
      cleanup();
    });

// 暴露方法给父组件
    defineExpose({
      addSensor,
      removeSensor,
      addPoint,
      removePoint,
      transferPlaneDataTo3dData,
      mousePosition,
    });
</script>

<template>
  <div class="cylinder-face-3d" :style="{ width: renderParams.width + 'px', height: renderParams.height + 'px' }">
    <div class="title">
      鼠标 x:{{ mousePosition.x.toFixed(1) }} y:{{ mousePosition.y.toFixed(1) }} z:{{ mousePosition.z.toFixed(1) }}
    </div>
    <div ref="threeBoxRef" class="view-content"></div>
    <!-- 传感器编号显示 -->
    <template v-for="(sensor, index) in sensors" :key="index">
      <div class="sensor-label" :style="sensor.dynamicStyle">
        {{ sensor.id }}
      </div>
    </template>
  </div>
</template>

<style scoped lang="scss">
.cylinder-face-3d {
  width: 100%;
  height: 100%;
  background-color: #f0f4f8;
  border: 1px solid #e0e0e0;
  border-radius: 4px;
  overflow: hidden;
  position: relative;
  display: flex;
  flex-direction: column;
}

.title {
  position: relative;
  top: 0;
  left: 0;
  z-index: 100;
  width: 100%;
  text-align: center;
  font-size: 11px;
  background-color: transparent;
}

.view-content {
  width: 100%;
  height: 100%;
  position: relative;
}

.sensor-label {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 100;
  display: inline-block;
  line-height: 1;
  color: orangered;
  font-weight: bold;
  font-size: 13px;
  pointer-events: none; /* 避免影响鼠标交互 */
}

canvas {
  display: block;
}
</style>
